package com.miyuan.wm.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.miyuan.wm.aop.UserOperation;
import com.miyuan.wm.data.UserInfo;
import com.miyuan.wm.enums.ExceptionCodeEnum;
import com.miyuan.wm.exception.BaseException;
import com.miyuan.wm.mapper.RecordInOutMapper;
import com.miyuan.wm.mapper.RecordStorageMapper;
import com.miyuan.wm.pojo.RecordInOutEntity;
import com.miyuan.wm.pojo.RecordStorageEntity;
import com.miyuan.wm.request.AddRecordInRequestVo;
import com.miyuan.wm.request.AddRecordOutRequestVo;
import com.miyuan.wm.request.QueryRecordInOutRequestVo;
import com.miyuan.wm.response.BaseResponse;
import com.miyuan.wm.response.PageResponse;
import com.miyuan.wm.response.QueryRecordInOutResponseVo;
import com.miyuan.wm.service.RecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * @ClassName RecordServiceImpl
 * @Description 货物出入库业务类
 */
@Service
@Slf4j
public class RecordServiceImpl implements RecordService {

    @Autowired
    private RecordInOutMapper recordInOutMapper;

    @Autowired
    private RecordStorageMapper recordStorageMapper;

    @Override
    @Transactional
    @UserOperation("货物入库")
    public BaseResponse<Boolean> addRecordIn(UserInfo userInfo, AddRecordInRequestVo requestVo) {

        // 更新库存信息
        RecordStorageEntity storageEntity = queryRecordStorage(requestVo.getGoodId(), requestVo.getRespositoryId());
        if (ObjectUtils.isEmpty(storageEntity)) {
            // 新增
            storageEntity = new RecordStorageEntity();
            storageEntity.setGoodId(requestVo.getGoodId());
            storageEntity.setRespositoryId(requestVo.getRespositoryId());
            storageEntity.setNumber(requestVo.getNumber());
            recordStorageMapper.insert(storageEntity);
        } else {
            // 修改
            storageEntity.setNumber(storageEntity.getNumber() + requestVo.getNumber());
            recordStorageMapper.updateById(storageEntity);
        }

        // 保存入库记录
        RecordInOutEntity entity = new RecordInOutEntity();
        entity.setGoodId(requestVo.getGoodId());
        entity.setNumber(requestVo.getNumber());
        entity.setRespositoryId(requestVo.getRespositoryId());
        entity.setSupplierId(requestVo.getSupplierId());
        entity.setUserId(userInfo.getUserID());
        entity.setType(RecordService.RECORD_IN);
        recordInOutMapper.insert(entity);

        return BaseResponse.successOf(Boolean.TRUE);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @UserOperation("货物出库")
    public BaseResponse<Boolean> addRecordOut(UserInfo userInfo, AddRecordOutRequestVo requestVo) {

        // 更新库存信息
        RecordStorageEntity storageEntity = queryRecordStorage(requestVo.getGoodId(), requestVo.getRespositoryId());
        if (ObjectUtils.isEmpty(storageEntity)) {
            // 无库存，不能出货
            throw new BaseException(ExceptionCodeEnum.NONE_RECORD_STORAGE);
        } else {
            // 修改
            int oldNumber = storageEntity.getNumber();
            int newNumber = requestVo.getNumber();
            if (oldNumber < newNumber) {
                // 出货数大于库存数，无法出库
                throw new BaseException(ExceptionCodeEnum.LESS_THAN_STORAGE_QUANTITY);
            } else if (oldNumber > newNumber){
                // 出货数小于库存数，可以出库，更新库存
                storageEntity.setNumber(storageEntity.getNumber() - requestVo.getNumber());
                recordStorageMapper.updateById(storageEntity);
            } else {
                // 出货数等于库存数，可以出库，删除库存
                recordStorageMapper.deleteById(storageEntity.getId());
            }
        }

        // 保存出库记录
        RecordInOutEntity entity = new RecordInOutEntity();
        entity.setGoodId(requestVo.getGoodId());
        entity.setNumber(requestVo.getNumber());
        entity.setRespositoryId(requestVo.getRespositoryId());
        entity.setCustomerId(requestVo.getCustomerId());
        entity.setUserId(userInfo.getUserID());
        entity.setType(RecordService.RECORD_OUT);
        recordInOutMapper.insert(entity);

        return BaseResponse.successOf(Boolean.TRUE);
    }

    @Override
    public RecordStorageEntity queryRecordStorage(int goodId, int respositoryId) {
        Wrapper<RecordStorageEntity> wrapper = new EntityWrapper<>();
        wrapper.eq("good_id", goodId);
        wrapper.eq("respository_id", respositoryId);
        List<RecordStorageEntity> recordStorageEntities = recordStorageMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(recordStorageEntities)) {
            return null;
        }
        return recordStorageEntities.get(0);
    }

    @Override
    public PageResponse<List<QueryRecordInOutResponseVo>> listRecordInOut(QueryRecordInOutRequestVo requestVo) {
        Page<RecordInOutEntity> page = new Page<>(requestVo.getPageNumber(), requestVo.getPageSize());
        List<QueryRecordInOutResponseVo> inOutResponseVos = recordInOutMapper.listRecordInOut(page, requestVo);
        return PageResponse.newInstance(inOutResponseVos, page.getTotal(), page.getCurrent(), page.getSize());
    }
}
